import { AssetManager, Node, Prefab, Widget, error, instantiate, resources } from "cc";
import SystemBase from "../system/SystemBase";
import JNLayerBase from "./base/JNLayerBase";
import AnimsNodeUtil, { AnimsNodeInfo } from "../util/AnimsNodeUtil";
import { Tween } from "cc";
import { view } from "cc";
import { math } from "cc";
import { screen } from "cc";
import { ResolutionPolicy } from "cc";
import { UITransform } from "cc";

export enum JNLayerAnim{
    Enlarge = "Enlarge", //变大动画
    Smaller = "Smaller", //变小动画
    CubicInOutOpen = "CubicInOutOpen", //CubicInOut动画
    CubicInOutClose = "CubicInOutClose", //CubicInOut动画
    BackOutOpen = "BackOutOpen",
    BackInClose = "BackInClose",
}

//页面回调生命周期
export interface JNLayerCallback{
    onJNLoad?:Function,
    onJNClose?:Function
}

export interface JNLayerAnimInfo{
    front?:JNLayerAnim,
    back?:JNLayerAnim,
    frontTime?:number,
    backTime?:number,
    frontInfo?:AnimsNodeInfo,
    backInfo?:AnimsNodeInfo,
}

export interface JNLayerInfo{
    layer:string,
    uri:string,
    anims?:JNLayerAnimInfo,
}

export default class JNLayer extends SystemBase{
    
    //层
    layers:string[] = [];

    //Node 层
    layerMap:{[key:string]:Node} = {};

    //根节点
    root:Node;

    //页面
    views:{[key:string]:JNLayerInfo} = {};

    //当前打开的页面
    nodes:{[key:string]:Node[]} = {};

    //正在加载的页面
    loadViews:string[] = [];

    bind(root:Node){

        this.root = root;

        this.root.removeAllChildren();
        //初始化层
        this.layers.forEach(view => {
            // this.root.addChild();
            let node = new Node(view);
            this.layerMap[view] = node;
            let widget = node.addComponent(Widget);
            widget.isAlignBottom = true;
            widget.isAlignTop = true;
            widget.isAlignLeft = true;
            widget.isAlignRight = true;
            widget.bottom = widget.left = widget.right = widget.top = 0;
            this.root.addChild(node);
            widget.updateAlignment();
        })

    }

    //初始化
    async onInit(){

        if(!this.root) return;

    }

    //开启关闭Widget
    UpdateWidget(view:Node,enabled:boolean,isUpdate:boolean = true){
        if(view.getComponent(Widget)){
            isUpdate && view.getComponent(Widget)?.updateAlignment();
            view.getComponent(Widget).enabled = enabled;
        }
        // view.getComponentsInChildren(Widget).forEach(widget => {
        //     isUpdate && widget.updateAlignment();
        //     widget.enabled = enabled;
        // })
    }

    //打开页面
    async Open(key:string,args:any = null,callback:JNLayerCallback = {}){

        let info:JNLayerInfo;
        if(!key || !(info = this.views[key])) {
            console.info(`JNLayer 没有 ${key} 页面`);
            return;
        }


        if(info){
            let len = this.loadViews.push(key);
            let prefab = await this.loadPrefab(info);
            if(!(this.loadViews[len-1])) return;
            this.loadViews[len-1] = null;
            let view = instantiate(prefab);

            this.layerMap[info.layer].addChild(view);
            (this.nodes[key] || (this.nodes[key] = [])).push(view);

            this.UpdateWidget(view,false);

            let uiBase:JNLayerBase;
            if(uiBase = view.getComponent(JNLayerBase)){
                //播放动画
                if(info.anims){
                    this.onHandleAnim(info.anims,uiBase);
                }else{
                    //没有动画
                    this.UpdateWidget(view,true);
                }

                //打开生命周期
                let onJNLoad = uiBase.onJNLoad;
                uiBase.onJNLoad = (args) => {
                    uiBase.isJNClose = false;
                    callback.onJNLoad && callback.onJNLoad(args);
                    onJNLoad.bind(uiBase)(args);
                }
                //打开动画生命周期
                let onJNLoadAnimEnd = uiBase.onJNLoadAnimEnd;
                uiBase.onJNLoadAnimEnd = () => {
                    onJNLoadAnimEnd.bind(uiBase)(args);
                    (!uiBase.isJNClose) && this.UpdateWidget(view,true,false);

                }
                //关闭生命周期
                let onJNClose = uiBase.onJNClose;
                uiBase.onJNClose = () => {
                    uiBase.isJNClose = true;
                    this.UpdateWidget(view,false,false);
                    callback.onJNClose && callback.onJNClose();
                    onJNClose.bind(uiBase)();
                }

                //生命周期
                uiBase.onJNLoad(args);
            }

        }

    }

    //打开到关闭
    OpenToClose(key:string,args:any = null):Promise<void>{
        return new Promise<void>((resolve) => {
            this.Open(key,args,{onJNClose:resolve});
        });
    }


    //关闭Node页面
    CloseNode(node:Node){

        if(!node.isValid) return;

        if(node.getComponent(JNLayerBase)){
            node.getComponent(JNLayerBase).onJNClose();
        }else{
            node.destroy();
        }

        //删除记录
        Object.values(this.nodes).forEach(nodes => {
            let index = -1;
            if((index = nodes.indexOf(node)) >= 0){
                nodes.splice(nodes.indexOf(node),1);
            }
        })

    }

    //关闭
    Close(key:string){
        this.loadViews = this.loadViews.map(key => (key == key) ? null : key);
        let list = (this.nodes[key] || (this.nodes[key] = []));
        for (let index = 0; index < list.length; index++) {
            const node = list[index];
            
            if(node.isValid){
                if(node.getComponent(JNLayerBase)){
                    node.getComponent(JNLayerBase).onJNClose();
                }else{
                    node.destroy();
                }
            }
            list.splice(index,1);
            index--;

        }
    }

    //处理动画
    onHandleAnim(anims:JNLayerAnimInfo,node:JNLayerBase){

        //显示
        if(anims.front){
            let onJNLoad = node.onJNLoad;
            node.onJNLoad = function(data?:any) {
                AnimsNodeUtil[`on${anims.front}`](this.node,anims.frontTime || 0.5,anims.frontInfo,node.onJNLoadAnimEnd.bind(this));
                onJNLoad.bind(this)(data);
            }
        }
        //关闭
        if(anims.back){
            let onJNClose = node.onJNClose;
            node.onJNClose = function(data?:any) {
                AnimsNodeUtil[`on${anims.back}`](this.node,anims.backTime || 0.5,anims.backInfo);
                this.scheduleOnce(() => {
                    onJNClose.bind(this)(data);
                },anims.backTime || 0.5)
            }
        }

    }

    //加载页面
    async loadPrefab(info:JNLayerInfo):Promise<Prefab>{
        return new Promise(async resolve => {
            let res = await this.getBundle();
            res.load<Prefab>(info.uri,(error,data) => resolve(data));
        })
    }

    async getBundle():Promise<AssetManager.Bundle>{
        return resources;
    }

}
